#pragma once
#include "Common.h"

namespace kele
{
	// ����128KB����Ҫ������
	static const size_t sizeof_ptr = sizeof(void*); // ָ�볤��

	template<class T>
	class blockectPool
	{
	public:
		blockectPool() : _memory(nullptr), _freelist(nullptr), _remainder_size(0), _sizeof_T(sizeof(T))
		{
			if (_sizeof_T > _sysallocsize)
				_sysallocsize = 4 * _sizeof_T;
		}

		T* New()
		{
			T* newalloc = nullptr;
			// ������տգ��ʹӿ��Ŀռ���
			if (_freelist)
			{
				newalloc = (T*)_freelist;
				_freelist = *(void**)_freelist;
			}
			else // �¿��Ŀռ���
			{
				if (_sizeof_T > _remainder_size)// �ռ䲻��
				{
					_remainder_size = _sysallocsize;
					// _memory = (char*)malloc(_remainder_size);
					_memory = (char*)SystemAlloc(_remainder_size >> PAGE_SHIFT);
				}
				size_t blocksize = _sizeof_T > sizeof_ptr ? _sizeof_T : sizeof_ptr;
				newalloc = (T*)_memory;
				_memory += blocksize;
				_remainder_size -= blocksize;
			}
			// ��ʾ�����Զ������͵�Ĭ�Ϲ���
			new(newalloc)T;

			return newalloc;
		}

		void Delete(T* block)
		{
			// ��ʾ�����Զ������͵�����
			block->~T();

			// ͷ��
			// block��ͷsizeof_ptr�ֽ��Ǵ��next�ĵ�ַ
			// *(void**)block
			*(void**)block = _freelist;
			_freelist = block;
		}
		std::mutex _mtx;
	private:
		char* _memory;			 // ���Ŀռ��
		void* _freelist;		 // ���յĿռ�鵥����
		size_t _remainder_size;	 // memoryʣ��ռ��С
		size_t _sizeof_T;
		size_t _sysallocsize = 128 * 1024;
	};
}
